package com.hex.ds.hdtp.core.inf.metadata.service.impl;

import cn.hutool.core.util.StrUtil;
import com.hex.ds.hdtp.core.inf.metadata.entity.TableFieldsEntity;
import com.hex.ds.hdtp.core.inf.metadata.repository.ISourceConfInfoRepository;
import org.springframework.stereotype.Service;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * @Package com.hex.ds.hdtp.core.inf.metadata.service.impl
 * @ClassName GaussMethodService
 * @Description Gauss元数据管理服务类
 * @Author gj.xu
 * @Date 2024/3/4 18:20
 * @Version v2.0
 **/
@Service("GAUSS")
public class GaussMethodService extends AbstractSourceMethodService {

    public GaussMethodService(ISourceConfInfoRepository sourceConfInfoRepository) {
        super(sourceConfInfoRepository);
    }

    /**
     * @Method getSchemasSql
     * @Param
     * @Return java.lang.String
     * @Description 获取数据库Schemas的SQL
     * @Author gj.xu
     * @Date 2024/2/2 15:40
     * @Version V2.0
     */
    @Override
    public String getSchemasSql() {
        return "SELECT nspname FROM pg_namespace where nspacl is null ;";
    }

    /**
     * @Method getTablesSql
     * @Param schemaName
     * @Return java.lang.String
     * @Description 获取数据库Tables的SQL
     * @Author gj.xu
     * @Date 2024/2/2 15:44
     * @Version V2.0
     */
    @Override
    public String getTablesSql(String schemaName) {
        return StrUtil.format("SELECT tablename from pg_tables where schemaname = '{}'; ", schemaName);
    }

    @Override
    protected String queryProceduresContentSql(String schemaName, String proceduresName) {
        throw new RuntimeException("Gauss 暂未支持获取存储过程");
    }

    @Override
    protected String getProcedureContentFromResultSet(ResultSet resultSet) throws SQLException {
        throw new RuntimeException("Gauss 暂未支持获取存储过程");
    }

    @Override
    protected TableFieldsEntity toTableFieldsBean(Map<String, String> tableFieldsMap) {
        return null;
    }

    @Override
    protected String queryTableStructureSql(String schemaName, String tableName) {
        return null;
    }

    /**
     * @Method getTableShowCreateTableSql
     * @Param schema
     * @Param table
     * @Return java.lang.String
     * @Description 获取查询表建表语句的SQL
     * @Author gj.xu
     * @Date 2024/1/31 17:18
     * @Version V2.0
     */
    @Override
    public String getTableShowCreateTableSql(String schema, String table) {
        String querySql = "SELECT pg_get_tabledef('{}.{}') AS table_definition;";
        return StrUtil.format(querySql, schema, table);
    }


    /**
     * @Method getTableAllFieldNumSql
     * @Param schema
     * @Param table
     * @Return java.lang.String
     * @Description 获取字段总数SQL
     * @Author gj.xu
     * @Date 2024/2/1 11:12
     * @Version V2.0
     */
    @Override
    public String getTableAllFieldNumSql(String schema, String table) {
        String querySql = "SELECT attname AS column_name, format_type(atttypid, atttypmod) AS data_type\n" +
                "FROM pg_attribute\n" +
                "WHERE attrelid = '{}.{}'::regclass\n" +
                "AND attnum > 0; ";
        return StrUtil.format(querySql, schema, table);
    }


    /**
     * @Method getTableAllFieldNameSql
     * @Param schema
     * @Param table
     * @Return java.lang.String
     * @Description 获取所有字段名称SQL
     * @Author gj.xu
     * @Date 2024/2/1 11:44
     * @Version V2.0
     */
    @Override
    public String getTableAllFieldNameSql(String schema, String table) {
        String querySql = "SELECT column_name, data_type\n" +
                "FROM information_schema.columns\n" +
                "WHERE table_name = '{}'\n" +
                "  AND table_schema = '{}';";
        return StrUtil.format(querySql, schema, table);
    }

    /**
     * @Method getTablePartitionFieldSql
     * @Param schema
     * @Param table
     * @Return java.lang.String
     * @Description 获取分区字段的SQL
     * @Author gj.xu
     * @Date 2024/2/1 20:20
     * @Version V2.0
     */
    @Override
    public String getTablePartitionFieldSql(String schema, String table) {
        String querySql = "SELECT pg_get_tabledef('{}.{}') AS table_definition;";
        return StrUtil.format(querySql, schema, table);
    }

    /**
     * @Method getCreateTableBodySql
     * @Param columnName
     * @Param columnType
     * @Param columnExt
     * @Return java.lang.String
     * @Description 获取创建表时Body部分SQL
     * @Author gj.xu
     * @Date 2024/2/1 17:36
     * @Version V2.0
     */
    public String getCreateTableBodySql(String columnName, String columnType, String columnExt) {
        String querySql = "{} {}{},\n";
        return StrUtil.format(querySql, columnName, columnType, columnExt);
    }

    /**
     * @Method getCreateTablePartitionSql
     * @Param columnName
     * @Return java.lang.String
     * @Description 获取创建表时分区部分SQL
     * @Author gj.xu
     * @Date 2024/2/1 18:50
     * @Version V2.0
     */
    public String getCreateTablePartitionSql(String columnName) {
        String querySql = "PARTITION BY RANGE( {} )\n";
        return StrUtil.format(querySql, columnName);
    }

    /**
     * @Method getCreateTablePartitionSuffixSql
     * @Param columnName
     * @Return java.lang.String
     * @Description 获取创建表时分区suffix部分SQL
     * @Author gj.xu
     * @Date 2024/2/1 19:21
     * @Version V2.0
     */
    public String getCreateTablePartitionSuffixSql(String columnName) {
        String querySql = "( PARTITION P1 VALUES LESS THAN({}),PARTITION P2 VALUES LESS THAN(MAXVALUE) )";
        return StrUtil.format(querySql, columnName);
    }


    /**
     * @Method getCreateTableCommentSql
     * @Param schema
     * @Param table
     * @Param columnName
     * @Param columnComment
     * @Return java.lang.String
     * @Description 获取创建表时Comment部分SQL
     * @Author gj.xu
     * @Date 2024/2/1 19:20
     * @Version V2.0
     */
    public String getCreateTableCommentSql(String schema, String table, String columnName, String columnComment) {
        String querySql = "comment on column  {}.{}.{} is '{}';\n";
        return StrUtil.format(querySql, schema, table, columnName, columnComment);
    }

    /**
     * @Method getStrDataType
     * @Param
     * @Return java.util.List<java.lang.String>
     * @Description 获取字符数据类型
     * @Author gj.xu
     * @Date 2024/2/21 14:20
     * @Version V2.0
     */
    @Override
    public List<String> getStrDataType() {
        return Arrays.asList("CHAR", "CHARACTER", "NCHAR", "VARCHAR", "VARCHAR2", "NVARCHAR2", "CLOB", "TEXT");
    }

    /**
     * @Method getNumDataType
     * @Param
     * @Return java.util.List<java.lang.String>
     * @Description 获取数值数据类型
     * @Author gj.xu
     * @Date 2024/2/21 15:10
     * @Version V2.0
     */
    @Override
    public List<String> getNumDataType() {
        return Arrays.asList("TINYINT", "SMALLINT", "INTEGER", "BINARY_INTEGER", "BIGINT", "NUMERIC", "DECIMAL", "NUMBER", "FLOAT", "FLOAT4", "FLOAT8", "BINARY_DOUBLE", "DEC");
    }

    /**
     * @Method getAccuracyDataType
     * @Param
     * @Return java.util.List<java.lang.String>
     * @Description 获取精度数据类型
     * @Author gj.xu
     * @Date 2024/2/21 15:32
     * @Version V2.0
     */
    @Override
    public List<String> getAccuracyDataType() {
        return Arrays.asList("NUMERIC", "DECIMAL", "NUMBER", "BINARY_DOUBLE", "FLOAT", "DEC", "INTEGER");
    }
}
